import express from "express";
import multiparty from "multiparty";
import path from "node:path";
import Result from "../../common/result.js";
import { saveChunk } from "../../utils/file.js";
import fse from "fs-extra";
import { UPLOAD_PATH } from "../../const/index.js";

const uploadRouter = express.Router();

uploadRouter.post("/chunk", async (req, res) => {
  try {
    const form = new multiparty.Form();
    form.parse(req, async (err, fields, files) => {
      if (err) {
        return res.send(
          Result.error(
            { data: null, message: "上传失败", reason: err },
            "上传失败"
          )
        );
      }
      const fileHash = fields["fileHash"][0];
      const chunkHash = fields["chunkHash"][0];
      const chunkPath = path.join(UPLOAD_PATH, fileHash);
      saveChunk(chunkPath, files["chunk"][0]["path"], chunkHash);
      return res.send(
        Result.success({ data: null, message: "上传成功" }, "上传成功")
      );
    });
  } catch (error) {
    return res.send(
      Result.error(
        { data: null, message: "上传失败", reason: err },
        "上传失败",
        101
      )
    );
  }
});

uploadRouter.post("/merge", async (req, res) => {
  try {
    const { fileHash, fileName, chunkSize } = req.body;
    const mergePath = path.join(UPLOAD_PATH, fileHash);
    const targerFilePath = path.join(
      UPLOAD_PATH,
      `${fileHash}${path.extname(fileName)}`
    );
    if (!fse.existsSync(mergePath)) {
      return res.send(null, "合并失败", 101);
    }
    const chunkFiles = await fse.readdir(mergePath);
    chunkFiles.sort((a, b) => {
      return a.split("-")[1] - b.split("-")[1];
    });
    const list = chunkFiles.map((chunkName, index) => {
      return new Promise((resolve, _reject) => {
        const chunkPath = path.join(mergePath, chunkName);
        const writeStream = fse.createWriteStream(targerFilePath, {
          start: index * chunkSize,
          end: (index + 1) * chunkSize,
        });
        const readStream = fse.createReadStream(chunkPath);
        readStream.on("end", async () => {
          fse.unlinkSync(chunkPath);
          resolve();
        });
        readStream.pipe(writeStream);
      });
    });
    await Promise.all(list);
    await fse.rm(mergePath, { recursive: true });
    return res.send(
      Result.success(
        {
          fileHash,
        },
        "合并成功"
      )
    );
  } catch (error) {
    return res.send(null, "合并失败", 101);
  }
});

export default uploadRouter;
